package vn.demand.dragon.view
{
	import com.salesbuilder.control.TabManager;
	
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.ui.Keyboard;
	
	import flexed.widgets.alerts.alert;
	
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.controls.AdvancedDataGrid;
	import mx.controls.Alert;
	import mx.controls.Button;
	import mx.controls.CheckBox;
	import mx.controls.ComboBox;
	import mx.controls.TextInput;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
	import mx.controls.advancedDataGridClasses.AdvancedDataGridItemRenderer;
	import mx.events.AdvancedDataGridEvent;
	import mx.events.AdvancedDataGridEventReason;
	import mx.events.CloseEvent;
	import mx.events.FlexEvent;
	import mx.events.ValidationResultEvent;
	import mx.formatters.DateFormatter;
	import mx.managers.PopUpManager;
	import mx.validators.Validator;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;
	
	import vn.demand.dragon.CommonCommand;
	import vn.demand.dragon.FFIAApplicationFacade;
	import vn.demand.dragon.editor.EditorComboBox;
	import vn.demand.dragon.model.MasterdataProxy;
	import vn.demand.dragon.model.QuotationLinesProxy;
	import vn.demand.dragon.model.TaskProxy;
	import vn.demand.dragon.model.UserProxy;
	import vn.demand.dragon.view.components.ItemCompleteDialog;
	import vn.demand.dragon.view.components.TaskScreen;
	import vn.demand.utils.DpUtils;

	public class TaskScreenMediator extends Mediator
	{
		public static const NAME:String = "TaskScreenMediator";
		
		private var quotationLinesProxy:QuotationLinesProxy;
		private var masterdataProxy:MasterdataProxy;
		private var taskProxy:TaskProxy;
		private var userProxy:UserProxy;
		private var beingClose:Boolean = false;
		
		private var projectVO:Object;
		
		public static function makeId(projectVO:Object, singleton:Boolean = false):String {
			if (singleton) {
				return NAME;
			}
        	return NAME + projectVO.project_id + "::";
        }
		
		public function TaskScreenMediator(projectVO:Object, mediatorName:String, viewComponent:Object)
		{
			super(mediatorName, viewComponent);
			
			this.projectVO = projectVO;
			
			masterdataProxy = facade.retrieveProxy(MasterdataProxy.NAME) as MasterdataProxy;
			taskProxy = facade.retrieveProxy(TaskProxy.NAME) as TaskProxy;
			userProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;
			quotationLinesProxy = facade.retrieveProxy(QuotationLinesProxy.NAME) as QuotationLinesProxy;
			
			taskScreen.addEventListener(TaskScreen.TASK_SCREEN_UI_CREATED, prepareData);
		}
		
		public function prepareData(event:Event):void {
			for each (var col:AdvancedDataGridColumn in gridTasks.groupedColumns) {
				switch (col.dataField) {
					case 'task_quotation':
					case 'task_item':
					case 'task_cargo_type':
					case 'task_container':
					case 'task_method':
					case 'task_shipping_type':
					case 'task_unit':
						col.labelFunction = comboBoxLabelFunction;
						break;
										
					case 'line_no':
						col.labelFunction = lfRowNum;
						break;
					case 'task_is_complete':
						col.labelFunction = lfTaskComplete;
						break
				}
			}
			
			gridTasks.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_BEGIN, makeEditor);
			gridTasks.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_END, processData);
			
			taskScreen.addEventListener(TaskScreen.SAVE_TASKS, onSaveTask);
			taskScreen.addEventListener(TaskScreen.RELOAD_TASKS, onReloadTask);
			taskScreen.addEventListener(TaskScreen.BROWSE_REFERENCE, onBrowseReference);
			taskScreen.addEventListener(TaskScreen.REMOVE_TASK, onRemoveTask);
			taskScreen.addEventListener(TaskScreen.TASK_SCREEN_CLOSE, onCloseForm);
			taskScreen.addEventListener(TaskScreen.COMPLETE_ALL_TASKS, onCompleteAll);
			
			createContextMenu();
			
			gridTasks.contextMenu = m;
			
			doLoadTasks();
			
			var canEdit:Boolean = DpUtils.isTrue(userProxy.userInfo.task_edit);
			if (!canEdit || masterdataProxy.isProjectProcessed(this.projectVO)) {
				taskScreen.canEdit = false;
				removeMenu.enabled = false;
			}
		}
		
		public function onCompleteAll(event:Event):void {
			var errors:String = "";
			var hasTaskForComplete:Boolean = false;
			for(var i=0; i < gridTasks.dataProvider.length; i++) {
				var sel = gridTasks.dataProvider.getItemAt(i);
				if (DpUtils.isTrue(sel.task_is_complete)) {
					continue;
				}
				if (Number(sel.task_item) == 0) {
    				continue;
	        	}
				hasTaskForComplete = true; 
	        	if (Number(sel.task_quotation) == 0 || Number(sel.task_quotation) == NaN) {
	        		errors += 'Row [' + i + ']: Quotation can not be empty\n';
	        	}
	        	errors += validateItem(sel, i);
			}
			if (!hasTaskForComplete) {
				alert.error('There are no tasks for completing!');
				return;
			}
			if (errors.length > 0) {
				alert.error('You can not complete all tasks. There are errors: \n' + errors);
				return;
			}
			var dialog:ItemCompleteDialog = PopUpManager.createPopUp(taskScreen, ItemCompleteDialog, true) as ItemCompleteDialog;
			PopUpManager.centerPopUp(dialog);
			dialog.title = "Do you want to complete all these tasks?";
			dialog.completed_date.selectedDate = new Date();
			dialog.caller = this;
			dialog.callback = confirmCompleteAllTask;
		}
		
		public function confirmCompleteAllTask(event:CloseEvent, completedDate:String):void {
        	var errors:String = "";
			for(var i=0; i < gridTasks.dataProvider.length; i++) {
				var sel = gridTasks.dataProvider.getItemAt(i);
				if (DpUtils.isTrue(sel.task_is_complete)) {
					continue;
				}
				if (Number(sel.task_quotation) == 0) {
    				continue;
	        	} 
				sel.task_is_complete = true;
				sel.task_end_date = completedDate;
				taskScreen.enableSave = true;
			}
        }
		
		public function doLoadTasks():void {
			quotationLinesProxy.loadQuotationLines();
		}
		
		public function onRemoveTask(event:Event):void {
			doRemoveTask(gridTasks.selectedIndex);
		}
		
		public function onBrowseReference(event:Event) {
			sendNotification(FFIAApplicationFacade.BROWSE_REFERENCE_LIST);
		}
		
		var m:ContextMenu;
		var copyMenu:ContextMenuItem;
        var pasteMenu:ContextMenuItem;
        var removeMenu:ContextMenuItem;
        
        private function createContextMenu():void {
		    m = new ContextMenu();
		    m.hideBuiltInItems();
		    var customItemsArr:Array = new Array();
		    copyMenu = new ContextMenuItem("Copy Row");
		    pasteMenu = new ContextMenuItem("Patse Row");
		    removeMenu = new ContextMenuItem("Remove Row");
		    
		    copyMenu.addEventListener("menuItemSelect", copyHandler);
		    pasteMenu.addEventListener("menuItemSelect", pasteHandler);
		    removeMenu.addEventListener("menuItemSelect", removeHandler);
		    
		    pasteMenu.enabled = false;
		    
		    customItemsArr.push(copyMenu);
		    customItemsArr.push(pasteMenu);
		    customItemsArr.push(removeMenu);
		    
		    removeMenu.enabled = taskScreen.canEdit;
		    
		    m.customItems = customItemsArr;
	    }
	    
	    private var copyItem:Object = null;
	    
	    private function copyHandler(e:ContextMenuEvent):void
	    {
	    	var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTasks.selectedIndex;
	    	}
	    	if (itemIndex < 0) return;
	    	pasteMenu.enabled = true;	    	
		    copyItem = gridTasks.dataProvider.getItemAt(itemIndex);
	    }
	    
	    private function pasteHandler(e:ContextMenuEvent):void
	    {
	    	if (masterdataProxy.isProjectProcessed(projectVO)) {
	    		return;
	    	}
		    var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTasks.selectedIndex;
	    	}
	    	if (itemIndex < 0) return;
	    	taskProxy.copyTask(projectVO, copyItem, itemIndex);
	    	taskScreen.enableSave = true;
	    }
	    
	    private function removeHandler(e:ContextMenuEvent):void
	    {
	    	if (masterdataProxy.isProjectProcessed(projectVO)) {
	    		return;
	    	}
	    	var itemIndex:Number = -1;
	    	if (e.mouseTarget is AdvancedDataGridItemRenderer) {
		    	itemIndex = AdvancedDataGridItemRenderer(e.mouseTarget).listData.rowIndex;
	    	} else {
	    		itemIndex = gridTasks.selectedIndex;
	    	}
	    	if (itemIndex < 0) {
	    		alert.error("You don't select any row to remove!");
	    		return;
	    	}
		    doRemoveTask(itemIndex);
	    }
		
		function onSaveTask(event:Event):void {
			if (doSaveTask()) {
				sendNotification(FFIAApplicationFacade.TASK_UPDATED);
			}; 
		}
		
		private function onCloseForm(event:Event):void {
			if (taskScreen.enableSave) {
				alert.confirm("Do you want to save before close?", handleConfirmSave, Alert.CANCEL);
			} else {
				beingClose = true;
				doClose();
			}
        }
        
        private function handleConfirmSave(event:CloseEvent) {
        	beingClose = true;
        	if (event.detail == Alert.CANCEL) {
        		return;
        	}
        	if (event.detail == Alert.YES && !doSaveTask()) {
        		beingClose = false;
        	}
        	if (beingClose) {
        		doClose();        		
        	}
        }
        
        private function handleConfirmSaveBeforeLoadAnother(event:CloseEvent) {
        	if (event.detail == Alert.CANCEL) {
	        	sendNotification(CommonCommand.CANCEL_FOR_LOAD_REFERENCE, projectVO, NAME);
        		return;
        	}
        	if (event.detail == Alert.YES) {
        		if (!doSaveTask()) {
	        		sendNotification(CommonCommand.CANCEL_FOR_LOAD_REFERENCE, projectVO, NAME);
	        		return;
        		}
        	}
    		gridTasks.dataProvider = null;
			taskScreen.enableSave = false;
    		sendNotification(CommonCommand.OK_FOR_LOAD_REFERENCE, projectVO, NAME);
        }
        
        private function doClose():void {
        	TabManager.removeTab(taskScreen);
        	sendNotification(CommonCommand.CLOSE_FINISH_PROJECT_TASKS_PANEL, projectVO);	
        }
		
		function doSaveTask():Boolean {
			if (!doValidate()) {
				alert.error(gridTasks.errorString);
				return false;
			}
			taskScreen.enableSave = false;
			
			var cursor:IViewCursor = ICollectionView(gridTasks.dataProvider).createCursor();
        	while (!cursor.afterLast) {
        		RIALogger.debug(this, "remove?: qitem_item: " + Number(cursor.current['qitem_item']));
        		if ((Number(cursor.current['task_quotation']) <= 0)) {
        			cursor.remove();
        		} else {
        			cursor.moveNext();
        		}
        	} 
			
			taskProxy.saveTasks(projectVO);
			return true;
		}
		
		function onReloadTask(event:Event):void {
			if (taskScreen.enableSave) {
	        	alert.confirm("Data has being edited, do you want to reload?", function(e:CloseEvent) {
	        		if (e.detail == Alert.YES) {
	        			sendNotification(FFIAApplicationFacade.REFRESH_REFERENCE_LINES, null, projectVO.project_id);	        			
	        		}
	        	});
        	} else {
        		sendNotification(FFIAApplicationFacade.REFRESH_REFERENCE_LINES, null, projectVO.project_id);
        	}			
		}
		
		public function get taskScreen():TaskScreen
		{
            return viewComponent as TaskScreen;
        }
        
        public function get gridTasks():AdvancedDataGrid {
			return taskScreen.gridTasks;
		}
		
		public function doValidate():Boolean {
        	var errors:String = "";
        	var i:int = 1;
        	for each (var item:Object in gridTasks.dataProvider) {
        		if (Number(item.task_quotation) == 0 || Number(item.task_quotation) == NaN) {
        			continue;
        		}
        		errors += validateItem(item, i);
        		i++;
        	}
        	if (errors.length > 0) {
        		gridTasks.errorString = errors;
        		return false;
        	}
    		gridTasks.errorString = "";
    		return true;
        }
        
        public function validateItem(item:Object, i:int):String {
        	var errors:String = "";
    		if (Number(item.task_item) == 0) {
    			errors += 'Row [' + i + ']: Service can not be empty\n';
    		}
    		if (Number(item.task_cargo_type) == 0) {
    			errors += 'Row [' + i + ']: Cargo Type can not be empty\n';
    		}
    		if (Number(item.task_shipping_type) == 0) {
    			errors += 'Row [' + i + ']: Shipping Type can not be empty\n';
    		}
    		if (Number(item.task_figure) == 0) {
    			errors += 'Row [' + i + ']: Shipping Type can not be empty\n';
    		}
    		return errors;
        }
        
		/**
         * List all notifications this Mediator is interested in.
         * <P>
         * Automatically called by the framework when the mediator
         * is registered with the view.</P>
         * 
         * @return Array the list of Nofitication names
         */
        override public function listNotificationInterests():Array 
        {
            return [ 
            	CommonCommand.CLOSE_TAB,
            	FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_SUCCESS,
            	FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_FAILED,
            	FFIAApplicationFacade.LOAD_MASTERDATA_SUCCESS,
            	FFIAApplicationFacade.LOAD_MASTERDATA_FAILED,
            	FFIAApplicationFacade.LOAD_QITEMS_LIST_SUCCESS,
            	FFIAApplicationFacade.LOAD_QITEMS_LIST_FAILED,
            	FFIAApplicationFacade.LOAD_TASKS_BY_REFERENCE_FAILED,
            	FFIAApplicationFacade.LOAD_TASKS_BY_REFERENCE_SUCCESS,
            	FFIAApplicationFacade.TASK_UPDATED,
            	FFIAApplicationFacade.TASK_UPDATE_FAILED,
            	FFIAApplicationFacade.REFRESH_REFERENCE_LINES,
            	CommonCommand.BEFORE_LOAD_REFERENCE
			];
        }
        
        /**
         * Handle all notifications this Mediator is interested in.
         * <P>
         * Called by the framework when a notification is sent that
         * this mediator expressed an interest in when registered
         * (see <code>listNotificationInterests</code>.</P>
         * 
         * @param INotification a notification 
         */
        override public function handleNotification( note:INotification ):void 
        {
        	RIALogger.debug(this, "handleNotification: " + Number(projectVO.project_id));
            switch ( note.getName() ) 
			{
				case CommonCommand.CLOSE_TAB:
					if (note.getBody() == taskScreen) {
						onCloseForm(new Event('onCloseTask'));
					}
					break;
				case FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_SUCCESS:
					if (note.getType() != NAME) {
						return;
					}
					this.projectVO = note.getBody();
					
					if (masterdataProxy.isProjectProcessed(this.projectVO)) {
						taskScreen.canEdit = false;
						removeMenu.enabled = false;
					} else {
						taskScreen.canEdit = true;
						removeMenu.enabled = true;
					}
					
					taskProxy.reinit(projectVO);
					taskProxy.tasksDP.addItem(taskProxy.newTask());
                	gridTasks.dataProvider = taskProxy.tasksDP;
					
					quotationLinesProxy.reinit(projectVO);
					
					RIALogger.debug(this, "doLoadTasks after load in project navigation");
					this.doLoadTasks();
					
					break;
				case FFIAApplicationFacade.LOAD_REFERENCE_DETAIL_FAILED:
					break;
				case FFIAApplicationFacade.LOAD_QITEMS_LIST_SUCCESS:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					taskProxy.loadTaskByReference();
					break;
                
                case FFIAApplicationFacade.LOAD_TASKS_BY_REFERENCE_SUCCESS:
//                	if (String(note.getBody()) != TaskProxy.makeId(projectVO)) {
//                		return;
//                	}
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
                	taskProxy.tasksDP.addItem(taskProxy.newTask());
                	gridTasks.dataProvider = taskProxy.tasksDP;
                	gridTasks.errorString = null;
                	taskScreen.enableSave = false;
                	break;
				
				case FFIAApplicationFacade.LOAD_TASKS_BY_REFERENCE_FAILED:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
                	taskScreen.gridTasks.errorString = note.getBody().toString();
                	break;
				
				case FFIAApplicationFacade.LOAD_QITEMS_LIST_FAILED:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					taskScreen.gridTasks.errorString = note.getBody().toString();
					break;
				case FFIAApplicationFacade.TASK_UPDATED:
					if (beingClose) {
						return;
					}
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					alert.info("Tasks updated");
					taskProxy.tasksDP.addItem(taskProxy.newTask());
					break;
				case FFIAApplicationFacade.TASK_UPDATE_FAILED:
					if (beingClose) {
						return;
					}
					alert.error(note.getBody() as String);
					taskProxy.tasksDP.addItem(taskProxy.newTask());
					break;
				case FFIAApplicationFacade.REFRESH_REFERENCE_LINES:
					if (Number(note.getType()) != Number(projectVO.project_id)) {
		        		return;
		        	}
					doLoadTasks();
					break;
				case CommonCommand.BEFORE_LOAD_REFERENCE:
					if (note.getType() != NAME) {
						return;
					}
					if (taskScreen.enableSave) {
						alert.confirm("Do you want to save before load another Reference?", handleConfirmSaveBeforeLoadAnother, Alert.CANCEL);
					} else {
						gridTasks.dataProvider = null;
						taskScreen.enableSave = false;
						sendNotification(CommonCommand.OK_FOR_LOAD_REFERENCE, projectVO, NAME);
					}
					break;
            }
        }       
        	
        			
        public function makeEditor(event:AdvancedDataGridEvent):void {				
			var columnName:String = gridTasks.columns[event.columnIndex].dataField;
			var cbDataProvider:Object = null;
			var cbLabelFunction:Function = null;		
			var cbLabelField:String = null;		
			var cbKeyField:String = null;
			var useEditorComboBox = true;
			
			var sel:Object = gridTasks.dataProvider.getItemAt(gridTasks.selectedIndex);
			if (DpUtils.isTrue(sel.task_is_complete)) {
				event.preventDefault();
				return;
			} 
			switch(columnName) {
				case 'task_quotation':
					cbDataProvider = quotationLinesProxy.quotationOfCustomer;
					cbLabelField = 'quote_code';  
					cbKeyField = 'qitem_quotation';
					break;
				
				case 'task_item':
					cbDataProvider = quotationLinesProxy.getServicesOfQuotation(sel);
					cbLabelFunction = comboBoxItemLabelFunction;  
					cbKeyField = 'qitem_item';
					break;
				
				case 'task_cargo_type':
					cbDataProvider = quotationLinesProxy.getCargoTypeDP(sel);
					cbLabelFunction = comboBoxCargoTypeLabelFunction;  
					cbKeyField = 'qitem_cargo_type';
					break;
					
				case 'task_container':
					cbDataProvider = quotationLinesProxy.getContainerDP(sel);
					cbLabelFunction = comboBoxContainerLabelFunction;  
					cbKeyField = 'qitem_container';
					break;
	
				case 'task_method':
					cbDataProvider = quotationLinesProxy.getMethodDP(sel);
					cbLabelFunction = comboBoxMethodLabelFunction;  
					cbKeyField = 'qitem_method';
					break;
					
				case 'task_shipping_type':
					cbDataProvider = quotationLinesProxy.getShippingTypeDP(sel);
					cbLabelFunction = comboBoxShippingTypeLabelFunction;  
					cbKeyField = 'qitem_shipping_type';
					break;
				case 'task_place_from':
					cbDataProvider = quotationLinesProxy.getPlaceFromDP(sel);
					cbLabelField = 'qitem_place_from';
					cbKeyField = 'qitem_place_from';
					useEditorComboBox = false;
					break;
				case 'task_place_to':
					cbDataProvider = quotationLinesProxy.getPlaceToDP(sel);
					cbLabelField = 'qitem_place_to';
					cbKeyField = 'qitem_place_to';
					useEditorComboBox = false;
					break;
				case 'task_truck_detention':
					cbDataProvider = quotationLinesProxy.getTruckDP(sel);
					cbLabelField = 'qitem_truck_detention';
					cbKeyField = 'qitem_truck_detention';
					useEditorComboBox = false;
					break;
				case 'task_unit':
					cbDataProvider = quotationLinesProxy.getUnitDP(sel);
					cbLabelFunction = comboBoxUnitLabelFunction;  
					cbKeyField = 'qitem_unit';
					break;
				case 'task_condition':
					cbDataProvider = quotationLinesProxy.getConditionDP(sel);
					cbLabelField = 'qitem_condition';
					cbKeyField = 'qitem_condition';
					useEditorComboBox = false;
					break;
				case 'task_is_complete':
					event.preventDefault();
	                gridTasks.createItemEditor(event.columnIndex, event.rowIndex);
	                var value = gridTasks.editedItemRenderer.data[columnName];
	                Button(gridTasks.itemEditorInstance).label = "Complete";
	                Button(gridTasks.itemEditorInstance).width = 100;
	                Button(gridTasks.itemEditorInstance).addEventListener(FlexEvent.BUTTON_DOWN, handleCompleteTask);
	                Button(gridTasks.itemEditorInstance).setFocus();
	                return;
			}               
            if (useEditorComboBox && null != cbDataProvider){
            	// Disable copying data back to the control.
                event.preventDefault();
                gridTasks.createItemEditor(event.columnIndex, event.rowIndex);
                var cb:EditorComboBox = EditorComboBox(gridTasks.itemEditorInstance);
                cb.dataProvider = cbDataProvider;
                if (cbLabelFunction != null) {
                	cb.labelFunction = cbLabelFunction;
                }
                if (cbKeyField != null) {
                	cb.keyField = cbKeyField;
                }
                if (cbLabelField != null) {
                	cb.labelField = cbLabelField;
                }
                cb.selectedData = gridTasks.editedItemRenderer.data[columnName];
                cb.setFocus();
            } else if (columnName == 'task_place_from' || columnName == 'task_place_to' || columnName == 'task_truck_detention' || columnName == 'task_condition') {
            	// Disable copying data back to the control.
                event.preventDefault();
                gridTasks.createItemEditor(event.columnIndex, event.rowIndex);
                var mxcb:ComboBox = ComboBox(gridTasks.itemEditorInstance);
                mxcb.dataProvider = cbDataProvider;
                RIALogger.debug(this, "mxComboBox dataProvider: ");
                RIALogger.debug(this, cbDataProvider.toString());
                if (cbLabelFunction != null) {
                	mxcb.labelFunction = cbLabelFunction;
                }                
                if (cbLabelField != null) {
                	mxcb.labelField = cbLabelField;
                }
                mxcb.selectedItem = gridTasks.editedItemRenderer.data[columnName];
                mxcb.setFocus();
            } else {
            	event.preventDefault();
                gridTasks.createItemEditor(event.columnIndex, event.rowIndex);
                TextInput(gridTasks.itemEditorInstance).text = String(gridTasks.editedItemRenderer.data[columnName]);
                TextInput(gridTasks.itemEditorInstance).addEventListener(KeyboardEvent.KEY_DOWN, handleKeyArrow);
                TextInput(gridTasks.itemEditorInstance).selectionBeginIndex = 0;
                TextInput(gridTasks.itemEditorInstance).selectionEndIndex = String(TextInput(gridTasks.itemEditorInstance).data).length;
                
                TextInput(gridTasks.itemEditorInstance).setFocus();
            }
            
            setupValidator(columnName, gridTasks.itemEditorInstance);
        }
        
        public function handleKeyArrow(event:KeyboardEvent):void {
        	if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP) {
        		event.stopPropagation();
            	var newEvent:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, false, false, Keyboard.ENTER, Keyboard.ENTER, 13, event.ctrlKey, event.altKey, event.keyCode == Keyboard.UP);
            	var b:Boolean = event.currentTarget.dispatchEvent(newEvent);
        	}            	
        }
        
        public function handleCompleteTask(event:Event):void {
    		var sel:Object = gridTasks.dataProvider.getItemAt(gridTasks.selectedIndex);
    		var errors:String = "";
        	var i:int = gridTasks.selectedIndex + 1
        	if (Number(sel.task_quotation) == 0 || Number(sel.task_quotation) == NaN) {
        		errors += 'Row [' + i + ']: Quotation can not be empty\n';
        	}
        	errors += validateItem(sel, i);
        	if (errors.length > 0) {
        		CheckBox(event.target).selected = false;
        		sel.task_is_complete = false;
        		gridTasks.dataProvider.itemUpdated(sel);
        		alert.error(errors);
        		return;
        	} else {
        		var dialog:ItemCompleteDialog = PopUpManager.createPopUp(taskScreen, ItemCompleteDialog, true) as ItemCompleteDialog;
    			PopUpManager.centerPopUp(dialog);
    			dialog.title = "Do you want to complete this task?";
    			dialog.completed_date.selectedDate = new Date();
    			dialog.caller = this;
    			dialog.callback = confirmCompleteTask;
        	}
        }
        
        public function confirmCompleteTask(event:CloseEvent, completedDate:String):void {
        	var sel:Object = gridTasks.dataProvider.getItemAt(gridTasks.selectedIndex);
        	if (event.detail == Alert.NO) {
        		sel.task_is_complete = false;
        		gridTasks.dataProvider.itemUpdated(sel);
        		return;
        	}
        	var errors:String = "";
        	var i:int = gridTasks.selectedIndex + 1
        	if (Number(sel.task_quotation) == 0 || Number(sel.task_quotation) == NaN) {
        		errors += 'Row [' + i + ']: Quotation can not be empty\n';
        	}
        	errors += validateItem(sel, i);
        	if (errors.length > 0) {
        		sel.task_is_complete = false;
        		gridTasks.dataProvider.itemUpdated(sel);
        		alert.error(errors);
        		return;
        	}
        	sel.task_is_complete = true;
        	sel.task_end_date = completedDate;
        	gridTasks.dataProvider.itemUpdated(sel);
        	taskScreen.enableSave = true;
        }
        
        //handle datagrid cell edit end event
        public function processData(event:AdvancedDataGridEvent):void {
        	if (event.reason == AdvancedDataGridEventReason.CANCELLED) {
        		return;
        	}
        	var colName:String = event.dataField;
        	if (curValidator != null) {
	    		var vResult:ValidationResultEvent = curValidator.validate();
	    		if (vResult.type == ValidationResultEvent.INVALID) {
	    			event.preventDefault();
	    			return;
	    		}
        	}
        	taskScreen.enableSave = true;
			var index:int = TaskProxy.arr.indexOf(event.dataField);
			var sel:Object = gridTasks.dataProvider.getItemAt(gridTasks.selectedIndex);
			if (index >= 0) {
				for (var i = index + 1; i < TaskProxy.arr.length; i++) {
					sel[TaskProxy.arr[i]] = "";
				}
				gridTasks.dataProvider.itemUpdated(sel);
			}
//			taskProxy.calTaskSaleAmount(sel);
//			if (colName == 'task_quotation') {
//				var selQuote:int = EditorComboBox(gridTasks.itemEditorInstance).selectedData;
//				var quoteVersion:String = quotationLinesProxy.getQuotationById(selQuote, 'quote_version');
//				sel.task_quotation_version = quoteVersion;
//				RIALogger.debug(this, "==>" + selQuote + " link task with quotation, quote_version = " + quoteVersion);
//			}
			
        	if (event.rowIndex == (gridTasks.dataProvider.length - 1)) {
        		var emptyItem:Object = taskProxy.newTask();
				gridTasks.dataProvider.addItem(emptyItem);
			}
        }
        
        public function comboBoxLabelFunction(item:Object, column:AdvancedDataGridColumn):String {
	    	switch (column.dataField) {
	    		case 'task_quotation':
	    			return quotationLinesProxy.getQuotationById(item[column.dataField]);	    		 	
	    		case 'task_item':
	    			return masterdataProxy.getItemById(item[column.dataField]) as String;
	    		case 'task_cargo_type':
	    			return masterdataProxy.getCargoTypeById(item[column.dataField]);
	    		case 'task_method':
	    			return masterdataProxy.getMethodById(item[column.dataField]);
	    		case 'task_container':
	    			return masterdataProxy.getContainerById(item[column.dataField]);
	    		case 'task_shipping_type':
	    			return masterdataProxy.getShippingTypeById(item[column.dataField]);
	    		case 'task_unit':
	    			return masterdataProxy.getUnitById(item[column.dataField]);
	    		case 'task_place_from':
	    			return item[column.dataField];
	    		case 'task_place_to':
	    			return item[column.dataField];
	    		default:
	    			return '';
	    	}
    	}
    	
    	public function lfRowNum(item:Object, col:int):String {
    		if (Number(item.task_quotation) > 0) {
	        	return String(gridTasks.dataProvider.getItemIndex(item) + 1);
    		}
    		return "";
        }
        
        private function comboBoxItemLabelFunction(item:Object):String {
            return masterdataProxy.getItemById(item.qitem_item) as String;
        }
        
        private function comboBoxCargoTypeLabelFunction(item:Object):String {
            return masterdataProxy.getCargoTypeById(item.qitem_cargo_type);
        }
        
        private function comboBoxContainerLabelFunction(item:Object):String {
            return masterdataProxy.getContainerById(item.qitem_container);
        }
        
        private function comboBoxMethodLabelFunction(item:Object):String {
            return masterdataProxy.getMethodById(item.qitem_method);
        }
        
        private function comboBoxShippingTypeLabelFunction(item:Object):String {
            return masterdataProxy.getShippingTypeById(item.qitem_shipping_type);
        }
        
        private function comboBoxUnitLabelFunction(item:Object):String {
            return masterdataProxy.getUnitById(item.qitem_unit);
        }
        
        public function doRemoveTask(selIndex:int):void {
        	if (selIndex < 0 || selIndex >= gridTasks.dataProvider.length) {
        		alert.error("You should select a row to remove");
        		return;
        	}
        	if (taskProxy.isTaskComplete(selIndex)) {
	    		alert.error("This task is completed. You can not remove it!");
	    		return;
	    	}
        	alert.confirm("Do you want to remove row at [" + (selIndex + 1) + "]?", function(e:CloseEvent) {
        		if (e.detail != Alert.YES) {
        			return;
        		}
        		taskProxy.removeTask(selIndex);
        		taskScreen.enableSave = true;
        		gridTasks.selectedIndex = -1;
        	});
        }
        
        function setupValidator(columnName:String, itemEditor:Object):void {
        	if (columnName == 'task_figure') {
        		TextInput(itemEditor).restrict = "0-9,.";
        		taskScreen.quantityValidator.source = itemEditor;
        		taskScreen.quantityValidator.property = 'text';
        		taskScreen.quantityValidator.required = true;
        		curValidator = taskScreen.quantityValidator;
        	}
        	else {
	        	curValidator = null;
        	}
        }
        
        private function lfTaskComplete(item:Object, col:int):String {
        	var df:DateFormatter = new DateFormatter();
        	df.formatString = "DD/MM/YYYY";
            return DpUtils.isTrue(item.task_is_complete) ? df.format(DpUtils.parseDate(item.task_end_date)) : '';
        }
        
        private var curValidator:Validator;
	}	
}